package lte

import (
	"fmt"
	"sort"

	"gitee.com/thubcc/mobile/utils"
)

type PSSSearchResult struct {
	Pos int     `json:"peak"`
	Df  float64 `json:"freqoff"`
	ID  int     `json:"id"`
	Amp float64 `json:"amp"`
}

type ScanRefSymResult struct {
	Cid int     `json:"cid"`
	Pos int     `json:"pos"`
	Amp float64 `json:"amp"`
	Df  float64 `json:"freqoff"`
}

type CellPeakResult struct {
	Pos int     `json:"pos"`
	Amp float64 `json:"amp"`
}

type CellCFOResult struct {
	Df float64 `json:"freqoff"`
}

type ChannelResult struct {
	Cid    int       `json:"cid"`
	TxPort int       `json:"tp"`
	RxPort int       `json:"rp"`
	I      []float64 `json:"I"`
	Q      []float64 `json:"Q"`
}

func APIPSSSearch(inf utils.RFInterface, init_f float64) (psr PSSSearchResult) {
	inf.Reset()
	rfd := inf.Raw(0, 100)
	inf.Run(100)
	psr.Df, psr.Amp, psr.ID, psr.Pos = ScanPssAll.SearchPSS(rfd, init_f)
	return
}

func APIScanRefSym(inf utils.RFInterface, init_f float64, txp, maxn int) (srsr []ScanRefSymResult, err error) {
	inf.Reset()
	rfd := inf.Raw(0, 2)
	inf.Run(2)
	idx, _, _ := ScanPssAll.SearchPSS2D(rfd, init_f)
	df := ScanPssAll.Frequency(idx[1])
	// log.Info("PSS 1 ", df)
	if df < 1e3 {
		pos := 9600 - 960 + idx[2] + 128
		id := idx[0]
		rs := ScanRefSym(rfd, id, txp, pos)
		for _, v := range rs[:maxn] {
			srsr = append(srsr, ScanRefSymResult{
				Amp: v.Amp,
				Cid: v.Cid,
				Pos: v.Pos,
				Df:  v.Df,
			})
		}
	} else {
		err = fmt.Errorf("Freqency offset %f", df)
	}
	return
}

func APICellPeak(inf utils.RFInterface, cid, port int) (cpr CellPeakResult) {
	inf.Reset()
	rfd := inf.Raw(0, 2)
	inf.Run(2)
	cpr.Pos, cpr.Amp = RefSignalPeak(rfd, cid, port)
	return
}

type ScanPeakResult struct {
	Cid    int     `json:"cid"`
	Pos    int     `json:"pos"`
	TxPort int     `json:"tx_port"`
	Amp    float64 `json:"amp"`
}

type ScanPeakResults []*ScanPeakResult

func (rs ScanPeakResults) Len() int           { return len(rs) }
func (rs ScanPeakResults) Less(i, j int) bool { return rs[i].Amp > rs[j].Amp }
func (rs ScanPeakResults) Swap(i, j int)      { rs[i], rs[j] = rs[j], rs[i] }
func APICellPeakAll(inf utils.RFInterface, port, n int) (rs ScanPeakResults) {
	inf.Reset()
	rfd := inf.Raw(0, 2)
	inf.Run(2)
	rs = make(ScanPeakResults, 0)
	for id := 0; id < 504; id++ {
		pos, amp := RefSignalPeak(rfd, id, port)
		rs = append(rs, &ScanPeakResult{id, pos, port, amp})
	}
	sort.Sort(rs)
	rs = rs[:n]
	return
}

func APICellCFO(inf utils.RFInterface, cid, port, pos int) (ccr CellCFOResult) {
	inf.Reset()
	rfd := inf.Raw(0, 100)
	inf.Run(100)
	ccr.Df = AFCSoltofCell(rfd, cid, port, pos)
	return
}

func APIChannel(inf utils.RFInterface, cid, port, pos int) (cr ChannelResult) {
	inf.Reset()
	rfd := inf.Raw(0, 2)
	inf.Run(2)
	ch := RefSignalH(rfd, cid, port, pos)
	cr.Cid = cid
	cr.TxPort = port
	cr.I = make([]float64, 74)
	cr.Q = make([]float64, 74)
	for i, v := range ch[54:] {
		cr.I[i] = real(v)
		cr.Q[i] = imag(v)
	}
	return
}
